package com.koron.standard.defectStock.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koron.standard.defectStock.bean.param.DefectMergeParam;
import com.koron.standard.defectStock.bean.po.DefectRef;
import com.koron.standard.defectStock.bean.po.DefectStock;
import com.koron.standard.defectStock.bean.query.DefectStockQuery;
import com.koron.standard.defectStock.bean.vo.DefectStockVo;
import com.koron.standard.defectStock.client.DefectClient;
import com.koron.standard.defectStock.mapper.DefectStockMapper;
import com.koron.standard.utils.StandardCodeTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 缺陷库服务类
 *
 * @author jzp
 * @since 2021/9/1
 */
@Service
public class DefectStockService extends ServiceImpl<DefectStockMapper, DefectStock> {

    @Autowired
    private DefectRefService defectRefService;

    @Autowired
    private DefectClient defectClient;

    public DefectStock getById(String id) {
        return getBaseMapper().getRealById(id);
    }

    public QueryWrapper<DefectStock> queryWrapper(DefectStockQuery<DefectStockVo> pageQuery) {
        // 1. 分页查询缺陷库数据
        QueryWrapper<DefectStock> wrapper = new QueryWrapper<>();
        // 1.1 缺陷子类和缺陷父类查询
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getParentTypeName()), "parent_type_name", pageQuery.getParentTypeName());
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getTypeName()), "type_name", pageQuery.getTypeName());

        // 1.2 关键字查询
        if (StrUtil.isNotEmpty(pageQuery.getKeyword())) {
            wrapper.and(w -> w.like("keyword", pageQuery.getKeyword())
                    .or()
                    .like("others", pageQuery.getKeyword()));
        }

        wrapper.like(StrUtil.isNotEmpty(pageQuery.getOthers()), "others", pageQuery.getOthers());
        wrapper.eq(pageQuery.getStatus()!=null, "status", pageQuery.getStatus());
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getDeptId()), "dept_id", pageQuery.getDeptId());
        wrapper.like(StrUtil.isNotEmpty(pageQuery.getDeptName()), "dept_name", pageQuery.getDeptName());
        if (CollUtil.isNotEmpty(pageQuery.getDates())) {
            wrapper.between("cds.create_time", pageQuery.getDates().get(0), pageQuery.getDates().get(1));
        }

        wrapper.eq("delete_flag", 0);

        if (CollUtil.isNotEmpty(pageQuery.getRefTimes())) {
            wrapper.between("ref_time", pageQuery.getRefTimes().get(0), pageQuery.getRefTimes().get(1));
        }
        return wrapper;
    }


    public Page<DefectStockVo> page(DefectStockQuery<DefectStockVo> pageQuery) {
        Page<DefectStockVo> defectStockPage = pageQuery.convertPage();
        // 现在改为由前端进行排序
        // // 默认根据num进行降序排序
        // List<OrderItem> orders = defectStockPage.getOrders();
        // orders.add(0, new OrderItem("num", false));

        QueryWrapper<DefectStock> wrapper = queryWrapper(pageQuery);

        // 1.end 缺陷库分页查询结果
        defectStockPage = getBaseMapper().selectPageVo(defectStockPage, wrapper);

        // 需求修改：缺陷关键字和缺陷工单需要对应
        List<Map<String,Integer>> result = (List<Map<String, Integer>>) defectClient.getDefectStock().getData();

        List<DefectStockVo> records = defectStockPage.getRecords();

        if (CollectionUtil.isNotEmpty(result)){
            Map<String,Integer> resultIndex = new HashMap<>();
            for (Map<String, Integer> map : result) {
                resultIndex.put(String.valueOf(map.get("code")),map.get("num"));
            }

            for (DefectStockVo record : records) {
                Integer num = resultIndex.get(record.getId());
                record.setNum(num);
            }
        }

        return defectStockPage;
    }

    public List<DefectStockVo> list(DefectStockQuery<DefectStockVo> pageQuery) {
        QueryWrapper<DefectStock> wrapper = queryWrapper(pageQuery);
        return getBaseMapper().selectPageVo(wrapper);
    }

    @Override
    public boolean saveOrUpdate(DefectStock defectStock) {
        // 1. 如果父类型的id为空且名称不为空则保存缺陷类型
        if (StrUtil.isEmpty(defectStock.getParentTypeName())) {
            defectStock.setParentTypeName("未分类");
        }
        if (StrUtil.isEmpty(defectStock.getTypeName())) {
            defectStock.setTypeName("无");
        }

        // 2. 设置code、status、num
        if (StrUtil.isEmpty(defectStock.getCode())) {
            defectStock.setCode(StandardCodeTools.getDefectStockCode());
        }
        if (defectStock.getStatus() == null) {
            // 默认启用
            defectStock.setStatus(1);
        }
        if (defectStock.getNum() == null) {
            defectStock.setNum(0);
        }

        // 3. 保存
        return super.saveOrUpdate(defectStock);
    }

    public boolean incrementRef(String id) {
        DefectStock defectStock = getById(id);
        DefectRef defectRef = new DefectRef();
        defectRef.setDefectId(id);
        defectRef.setDefectCode(defectStock.getCode());
        return defectRefService.save(defectRef);
    }

    /**
     * 将源id都合并到目标id中去
     */
    public void merge(DefectMergeParam defectMergeParam) {
        DefectStock targetDefect = getById(defectMergeParam.getTargetId());
        // 1. 修改源id的code为目标id的code
        LambdaUpdateWrapper<DefectStock> stockUpdateWrapper = new LambdaUpdateWrapper<DefectStock>();
        stockUpdateWrapper.set(DefectStock::getCode, targetDefect.getCode());
        stockUpdateWrapper.in(DefectStock::getId, defectMergeParam.getSourceIds());
        update(stockUpdateWrapper);

        // 2. 修改ref表中，源id的code为目标id的code
        LambdaUpdateWrapper<DefectRef> refUpdateWrapper = new LambdaUpdateWrapper<DefectRef>();
        refUpdateWrapper.set(DefectRef::getDefectCode, targetDefect.getCode());
        refUpdateWrapper.in(DefectRef::getDefectId, defectMergeParam.getSourceIds());
        defectRefService.update(refUpdateWrapper);

        // 3. 如果源数据有类似描述的数据，则拼接到目标数据中
        List<DefectStock> defectStocks = listByIds(defectMergeParam.getSourceIds());
        String other = defectStocks.stream().map(DefectStock::getOthers).collect(Collectors.joining(";"));
        if (StrUtil.isNotEmpty(other)) {
            LambdaUpdateWrapper<DefectStock> otherUpdateWrapper = new LambdaUpdateWrapper<DefectStock>();
            otherUpdateWrapper.set(DefectStock::getOthers, Objects.equals(targetDefect.getOthers(), null) ? "" : targetDefect.getOthers() + ";" + other);
            otherUpdateWrapper.eq(DefectStock::getId, defectMergeParam.getTargetId());
            update(otherUpdateWrapper);
        }

        // 4. 删除stock表中源id的数据
        removeByIds(defectMergeParam.getSourceIds());
    }

    public List<DefectStock> listByParent(String typeName) {
        LambdaQueryWrapper<DefectStock> wrapper = new LambdaQueryWrapper<>();
        // 如果typeName为空，则查询父类，如果不为空，则以typeName未父类来查询子类
        if (StrUtil.isEmpty(typeName)) {
            wrapper.groupBy(DefectStock::getParentTypeName);
        }else {
            wrapper.eq(DefectStock::getParentTypeName, typeName);
            wrapper.groupBy(DefectStock::getTypeName);
        }
        return list(wrapper);
    }

}
